﻿using Microsoft.IdentityModel.Tokens;
using SharedClassLibrary.DTOs;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Net.Http;
using System.Security.Claims;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace SharedClassLibrary
{
    public static class Generics
    {
        public static List<Claim> SetClaimsPrincipal(UserSession session)
        {
            var userClaims = new List<Claim>
            {
                new Claim(ClaimTypes.NameIdentifier,session.Id.ToString()),
                new Claim(ClaimTypes.Name,session.UserName),
                new Claim(ClaimTypes.Role,"admin")
            };
            return userClaims;
        }

        public static string GenerateToken(UserSession session, string signingKey, string issuer, string audience)
        {
            var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(signingKey));
            var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256);
            var userClaims = new List<Claim>
            {
                new Claim(ClaimTypes.NameIdentifier,session.Id.ToString()),
                new Claim(ClaimTypes.Name,session.UserName),
                new Claim(ClaimTypes.Role,"admin")
            };
            var token = new JwtSecurityToken(
                issuer: issuer,
                audience: audience,
                claims: userClaims,
                expires: DateTime.Now.AddDays(1),
                signingCredentials: credentials);
            return new JwtSecurityTokenHandler().WriteToken(token);
        }

        public static UserSession GetClaimsFromToken(string jwtToken)
        {
            var handler = new JwtSecurityTokenHandler();
            var token = handler.ReadJwtToken(jwtToken);
            var claims = token.Claims;

            int id = int.Parse(claims.FirstOrDefault(c => c.Type == ClaimTypes.NameIdentifier).Value);
            string username = claims.FirstOrDefault(c => c.Type == ClaimTypes.Name).Value;
            string role = claims.FirstOrDefault(c => c.Type == ClaimTypes.Role).Value;
            return new UserSession(id, username, role);
        }

        private static JsonSerializerOptions JsonOptions()
        {
            return new JsonSerializerOptions
            {
                AllowTrailingCommas = true,
                PropertyNameCaseInsensitive = true,
                PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
                UnmappedMemberHandling = JsonUnmappedMemberHandling.Skip
            };
        }

        public static string SerializeObject<T>(T obj) => JsonSerializer.Serialize(obj, JsonOptions());

        public static T DeserializeJsonString<T>(string json) => JsonSerializer.Deserialize<T>(json, JsonOptions());

        public static StringContent GenerateStringContent(string serializeObject) => new StringContent(serializeObject, Encoding.UTF8, "application/json");
    }
}
